package br.inf.mensageiro.socket;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;

import br.inf.mensageiro.main.Mensageiro;
import br.inf.mensageiro.util.GUID;
import br.inf.mensageiro.util.Parametro;
import br.inf.mensageiro.view.WindowView;

public class ClientSocket implements Runnable{	
	
	private String ip;
	private SSLSocketFactory sslsf=(SSLSocketFactory)SSLSocketFactory.getDefault();
	
	public ClientSocket(String ip){		
		this.ip=ip;
	}

	public void run() {
		SSLSocket socket=null;
		InputStream in=null;
		OutputStream out=null;
		WindowView chat=null;
		String chatId=null;
		try{
			socket= (SSLSocket)sslsf.createSocket(ip,Parametro.PORT_SERVER);
			final String[] enabledCipherSuites = { "SSL_DH_anon_WITH_RC4_128_MD5" };
			socket.setEnabledCipherSuites(enabledCipherSuites);
			
			in=socket.getInputStream();
			out=socket.getOutputStream();
			
			//sending the same id to the destination IP.
			chatId=GUID.generateId();			
			out.write(chatId.getBytes());
			out.write(-2);
			
			//sending the user name.
			String user=System.getProperty("user.name");
			out.write(user.getBytes());
			out.write(-2);

			chat=new WindowView(socket);			
			chat.setId(chatId);
			if(Mensageiro.ipwindowsViewIdMap.containsKey(ip)){
				List<String> chatIdList=Mensageiro.ipwindowsViewIdMap.get(ip);
				chatIdList.add(chatId);				
			}else{
				List<String> chatIdList=new ArrayList<String>();
				chatIdList.add(chatId);
				Mensageiro.ipwindowsViewIdMap.put(ip, chatIdList);
			}
			
			JTextPane mainArea=chat.getMa();
			Document doc=mainArea.getDocument();
			SimpleAttributeSet bold=new SimpleAttributeSet();
			StyleConstants.setBold(bold, true);
			
			StringBuffer msg=new StringBuffer();
			StringBuffer userName=new StringBuffer();
			
			boolean userNameValue=true;
			boolean msgValue=false;
			
			while(true){
				int value=in.read();	
				
				if(value==-1){
					chat.dispose();
					break;
				}
				
				if(((byte)value) ==-1){
					chat.setRemoteUserClosed(true);
				}
				
				if(msgValue){
					if(((byte)value) !=-2 && ((byte)value) !=-1){
						char ch=(char)value;
						msg.append(ch);
					}else if(((byte)value) !=-1){
						try{
							if(!chat.isVisible()){
								chat.setVisible(true);
								chat.toBack();
							}
							doc.insertString(doc.getLength(), chat.getRemoteUserName()+" : ",bold);
							doc.insertString(doc.getLength(), msg.toString()+"\n",null);
							mainArea.setCaretPosition(doc.getLength());	
						}catch(BadLocationException ble){
							ble.printStackTrace();
						}					
						msg=new StringBuffer();
					}
				}
				
				if(userNameValue){
					if(((byte)value) !=-2){
						char ch=(char)value;
						userName.append(ch);
					}else{
						chat.setRemoteUserName(userName.toString());
						chat.setTitle(userName.toString());
						chat.setVisible(true); 
						userNameValue=false;
						msgValue=true;
					}
				}				
			}
		}catch(IOException ioe){
			ioe.printStackTrace();			
		}finally{
			try{				
				List<String> chatIds=Mensageiro.ipwindowsViewIdMap.get(ip);
				chatIds.remove(chatId);	
				chat.setRemoteUserClosed(true);
				Mensageiro.windowViewMap.remove(chat.getId());
				in.close();
				out.close();
				socket.close();	
			}catch(IOException ioe){
				ioe.printStackTrace();
			}
		}		
	}
}
